#ifndef __SOCKOP_H__
#define __SOCKOP_H__

#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/un.h>
#include <event.h>
#include "buffer.h"

#define SOCKOP_READ_BUFSIZ (4096)

enum
{
    SOCK_TYPE_IPV4,
    SOCK_TYPE_IPV6,
    SOCK_TYPE_UNIX,
};

typedef struct sockop_ctx_
{
    union 
    {
        struct sockaddr_in sin; // ipv4地址信息
        struct sockaddr_in6 sin6; // ipv6地址信息
        struct sockaddr_un sun; // unix地址信息
    };
    struct sockaddr *sa;
    unsigned socklen;
    int sock;
    int type; // SOCK_TYPE_IPV4 SOCK_TYPE_IPV6 SOCK_TYPE_UNIX
    int cache_size;
    int (*cb)(char *, int, void *, void *);
    void *arg;
} sockop_ctx_t;

typedef struct sockop_conn_
{
    int sock;
    char *input;
    struct event ev_read;
    struct event ev_write;
    sockop_ctx_t *ctx;
    bf_buffer_t *output;
} sockop_conn_t;

int sockop_ipv4_tostruct(char *addr_ptr, unsigned short port, struct sockaddr_in *sin);
int sockop_ipv6_tostruct(char *addr_ptr, unsigned short port, struct sockaddr_in6 *sin6);
int sockop_usock_tostruct(char *path, struct sockaddr_un *sun);
int sockop_server_run(sockop_ctx_t *ctx, int log_init);
void sockop_server_exit(void);
int sockop_client_conn(sockop_ctx_t *ctx);
void sockop_client_exit(sockop_ctx_t *ctx);
int sockop_cmd_exec(int sock, char *line, FILE *fp);
int sockop_out(void *out, const char *format, ...);

#endif
